package com.neusoft.bizcore.notice.notification.service.impl;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.persistence.EntityNotFoundException;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.notice.notification.converter.NoticeTemplateConverter;
import com.neusoft.bizcore.notice.notification.dto.NoticeTemplateDTO;
import com.neusoft.bizcore.notice.notification.model.NoticeTemplate;
import com.neusoft.bizcore.notice.notification.repository.NoticeTemplateRepository;
import com.neusoft.bizcore.notice.notification.service.NoticeTemplateService;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class NoticeTemplateServiceImpl implements NoticeTemplateService {

    @Autowired
    private NoticeTemplateRepository noticeTemplateRepository;

    @Autowired
    private NoticeTemplateConverter noticeTemplateConverter;

    @Override
    public NoticeTemplateDTO create(final NoticeTemplateDTO dto) {
        // 校验模板类型是否重复
        final NoticeTemplate check =
                this.noticeTemplateRepository.findByType(dto.getType());
        if (check != null) {
            throw new UnitedException("每个类型只能创建一个模板", new Object[] {});
        }

        final NoticeTemplate model = this.noticeTemplateConverter.toModel(dto);
        this.noticeTemplateRepository.save(model);
        return this.noticeTemplateConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {
        NoticeTemplate model;
        try {
            model = this.noticeTemplateRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        this.noticeTemplateRepository.deleteById(id);
    }

    @Override
    public NoticeTemplateDTO update(final Long id, final NoticeTemplateDTO dto) {
        NoticeTemplate model;
        try {
            model = this.noticeTemplateRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        dto.setId(model.getId());
        // 校验模板类型是否重复
        final NoticeTemplate check =
                this.noticeTemplateRepository.findByType(dto.getType());
        if ((check != null) && !id.toString().equals(check.getId().toString())) {
            throw new UnitedException("每个类型只能创建一个模板", new Object[] {});
        }
        model = this.noticeTemplateConverter.toModel(dto);
        this.noticeTemplateRepository.save(model);

        return this.noticeTemplateConverter.toDTO(model);
    }

    @Override
    public List<NoticeTemplateDTO> index(final Searchable searchable) {
        final List<NoticeTemplate> models = this.noticeTemplateRepository.index(searchable);
        return this.noticeTemplateConverter.toListDTO(models);
    }

    @Override
    public NoticeTemplateDTO details(final Long id) {
        final NoticeTemplate model;
        try {
            model = this.noticeTemplateRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }
        return this.noticeTemplateConverter.toDTO(model);
    }

    @Override
    public Page<NoticeTemplateDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<NoticeTemplate> result = this.noticeTemplateRepository.search(pageable, searchable);
        return this.noticeTemplateConverter.toPageDTO(result);
    }

    @Override
    public NoticeTemplateDTO findByType(final String type) {
        final NoticeTemplate model = this.noticeTemplateRepository.findByType(type);
        if (model == null) {
            return null;
        }

        return this.noticeTemplateConverter.toDTO(model);
    }

    @Override
    public void downloadDefaultTemplate(final HttpServletResponse response) {
        try {

            final ClassPathResource classPathResource = new ClassPathResource("templates/noticeMail.ftl");

            final InputStream inputStream = classPathResource.getInputStream();
            final BufferedInputStream bis = new BufferedInputStream(inputStream);
            response.setCharacterEncoding("UTF-8");
            final OutputStream outputSream = response.getOutputStream();
            int len = 0;
            final byte[] buf = new byte[1024];
            while ((len = bis.read(buf, 0, 1024)) != -1) {
                outputSream.write(buf, 0, len);
            }
            outputSream.close();

        } catch (final IOException e) {
            NoticeTemplateServiceImpl.log.error("默认模板下载失败", e);
        }
    }

}
